package com.tiantian.lianhui.sdk;

import com.github.rholder.retry.*;
import com.google.gson.Gson;
import com.tiantian.lianhui.sdk.exception.ShortLinkParameterException;
import com.tiantian.lianhui.sdk.request.ShortLinkRequest;
import com.tiantian.lianhui.sdk.response.ShortLinkResponse;
import com.tiantian.lianhui.sdk.util.StrUtil;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;

import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author tiantian
 */
public class ShortLinkClient {

    public static ShortLinkResponse createShortLink(ShortLinkRequest shortLinkRequest) {
        // 验证非空字段
        String ak = shortLinkRequest.getAk();
        String originUrl = shortLinkRequest.getOriginUrl();
        String gid = shortLinkRequest.getGid();
        if (!StrUtil.isAllNotBlank(ak, originUrl, gid)) {
            throw new ShortLinkParameterException("ak, originUrl, gid 均不能为空");
        }
        // 校验日期格式
        Integer validDateType = shortLinkRequest.getValidDateType();
        if (validDateType != null) {
            if (!(validDateType == 0 || validDateType == 1)) {
                throw new ShortLinkParameterException("validDateType 只能输入0和1");
            }
        }
        Date validDate = shortLinkRequest.getValidDate();
        if (validDateType != null && validDateType == 0) {
            shortLinkRequest.setValidDate(null);
        }


        Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                .retryIfExceptionOfType(Throwable.class)
                .retryIfRuntimeException()                                                        // 发生运行时异常则重试
                .retryIfResult(result -> result.booleanValue() == Boolean.FALSE)                  // 重试条件 根据返回值判断重试
                .withStopStrategy(StopStrategies.stopAfterAttempt(3))                // 最大重试次数为3
                .withWaitStrategy(WaitStrategies.fixedWait(750, TimeUnit.MILLISECONDS))  // 重试间隔为0.75秒
                .build();
        AtomicReference<ShortLinkResponse> shortLinkResponseAtomicReference = new AtomicReference<>();
        Callable<Boolean> booleanCallable = () -> {
            HttpPost httpPost = new HttpPost("127.0.0.1:8000/api/short-link/v1/create");
            try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
                // 构造请求参数
                Gson gson = new Gson();
                HashMap<String, Object> map = new HashMap<>();
                map.put("ak", ak);
                map.put("gid", gid);
                map.put("originUrl", originUrl);
                map.put("validDateType", validDateType);
                map.put("validDate", validDate);
                httpPost.setEntity(new StringEntity(gson.toJson(map)));
                try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
                    if (response.getCode() != 200) {
                        return false;
                    }
                    HttpEntity entity = response.getEntity();
                    String responseBody = EntityUtils.toString(entity);
                    shortLinkResponseAtomicReference.set(gson.fromJson(responseBody, ShortLinkResponse.class));
                    return true;
                }
            }
        };
        try {
            retryer.call(booleanCallable);
        } catch (RetryException | ExecutionException e) {
            throw new RuntimeException("创建短链接失败", e);
        }
        return shortLinkResponseAtomicReference.get();
    }

}
